package utils;

import com.itextpdf.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.resource.XMLResource;
import org.xml.sax.InputSource;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class FreemarkerUtil {

    private static final Logger logger = Logger.getLogger(FreemarkerUtil.class);

    private static Configuration cfg;

    private static Configuration getCfg() {
        if (cfg == null) {
            cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            cfg.setDefaultEncoding("UTF-8");
            cfg.setClassLoaderForTemplateLoading(Thread.currentThread().getContextClassLoader(), "template");
            cfg.setNumberFormat("0.######");
            cfg.setTemplateUpdateDelay(6000);
        }
        return cfg;
    }

    private static ITextRenderer renderer = null;

    //初始化块，加载字体
    private static void init() {
        synchronized (logger) {
            if (renderer == null) {
                renderer = new ITextRenderer();
                ITextFontResolver fontResolver = renderer.getFontResolver();
                //该文件夹下放所需字体文件
                File fonts = new File(Thread.currentThread().getContextClassLoader().getResource("/fonts").getPath());
                File[] fileList = fonts.listFiles();
                if (null != fileList) {
                    for (int i = 0; i < fileList.length; i++) {
                        try {
                            fontResolver.addFont(fileList[i].getAbsolutePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                        } catch (Exception e) {
                            logger.error("error: ", e);
                        }
                    }
                }
            }
        }
    }

    public static String toHtml(Map<String, ?> paramMap, String filename) {
        return toHtml(paramMap, filename, "utf-8");
    }

    private static String toHtml(Map<String, ?> paramMap, String filename, String charset) {
        Configuration cfg = getCfg();
        Template t;
        try {
            t = cfg.getTemplate(filename, charset);
            Writer out = new StringWriter();
            t.process(paramMap, out);
            return out.toString();
        } catch (Exception e) {
            logger.error("协议模板转换html异常：", e);
        }

        return null;
    }

    /**
     * html生成pdf
     * @param html  填充参数后的html
     * @param pdfFileFullName 生成的pdf文件完整路径名
     * @return   
     */
    private static boolean html2PDF(String html, String pdfFileFullName) {
        init();

        OutputStream os = null;
        InputSource is = null;
        BufferedReader br = null;
        StringReader sr = null;
        //解决全局变量renderer并发的冲突
        synchronized (renderer) {
            try {
                sr = new StringReader(html);
                br = new BufferedReader(sr);
                is = new InputSource(br);

                //协议文件详细路径
                Document dom = XMLResource.load(is).getDocument();
                dom.normalizeDocument();
                renderer.setDocument(dom, null);
                renderer.layout();
                os = new FileOutputStream(pdfFileFullName);
                renderer.createPDF(os);
                logger.info("html转换pdf成功，协议文件名：" + pdfFileFullName);

                return true;

            } catch (Exception e) {
                logger.info("文档生成异常Exception，协议文件名：" + pdfFileFullName, e);
                return false;
            } finally {
                IOUtils.closeQuietly(os);
                IOUtils.closeQuietly(sr);
                IOUtils.closeQuietly(br);
                renderer.finishPDF();
            }
        }
    }

    /**
     * 获取模板，用freemark 填充参数生成字符串html
     * @param params
     * @return
     */
    public static boolean generatorPDF(String pdfFilePath, String templateFilePath, Map<String, ?> params) {
        try {
            String html = toHtml(params, templateFilePath);
            return html2PDF(html, pdfFilePath);

        } catch (Exception e) {
            logger.info("文档生成异常Exception", e);
            return false;
        }
    }

    public static void main(String[] args) {
        String idNoSplit = "11111";
        String[] split = idNoSplit.split("");
        String idNoSplitStr= StringUtils.join(split, ",");
        System.out.printf("=="+idNoSplitStr);
        Map<String,String> parm = new HashMap<>();
		parm.put("nameSize","2");
		parm.put("idNoSplit",idNoSplitStr);
		parm.put("numF","2.00");
		parm.put("realName1","武昭第一个");
		parm.put("realName2","武昭第二个");
		String toHtml = FreemarkerUtil.toHtml(parm, "wthk.ftl");
		System.out.printf("=="+toHtml);
    }

}
